home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
cpptask.exe
/
TSKDOS.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-07-26
|
20KB
|
973 lines
;
; CTask - DOS access module.
;
; Public Domain Software written by
; Thomas Wagner
; Patschkauer Weg 31
; D-1000 Berlin 33
; West Germany
;
;
; The DOS interrupt (and the related direct disk I/O interrupts) are
; not reentrant. Access to DOS thus has to be channelled such that no
; two tasks use DOS services simultaneously. However, there is one
; exception to this rule. Whenever DOS is waiting for the keyboard, it
; issues a special interrupt, INT 28h, to signal that background
; processing for functions > 0Ch may be performed. This is used in the
; DOS interface for CTask in the following manner:
;
; A task issuing a DOS interrupt will request one of two resources:
; "lower_dos" for functions <= 0C, "upper_dos" for functions > 0C.
; If a task gets access to "lower_dos", it will also request the
; "upper_dos" resource to lock out other tasks from interrupting.
; This "upper_dos" resource is shortly released on each INT 28, and
; then immediately reclaimed, with task priority temporarily raised
; to the maximum value. The first task waiting to execute a
; function > 0C will thus be scheduled to execute the request, but
; the resource will be reassigned to the INT 28 handler as soon as
; this request terminates, so the waiting task will not be delayed too
; long.
;
; There are two additional safety measures which have to be taken to
; avoid getting into conflicts with other resident background programs,
; especially the DOS PRINT background spooler:
;
; Before requesting any resource, the status of the DOS critical section
; flag is checked. If this flag is set, the task is made waiting for
; the flag to be cleared.
; Only the task that set the flag will be allowed access to DOS.
;
; Before actually executing the request, the status of the DOS in-use
; flag is checked. If this flag is set, the task enters a busy waiting
; loop, calling the scheduler so that the processor is not tied up.
;
; NOTE: The method for checking the status of DOS is described in-depth
; in the book "The MS-DOS Encyclopedia" from Microsoft Press, in
; the chapter on TSR programming. The logic in this module was
; developed without the help of this book, so if you compare
; the code here with the routines in the Encyclopedia, you may
; notice that not all re-entry conditions are checked here.
; According to my experience with debugging TSR's and CTask, the
; logic should be sufficient for all but the most obscure TSR's.
; If you want to be completely on the safe side, you might consider
; adding the more thorough checks listed in the Encyclopedia.
;
;
name tskdos
;
.model large
;
public _tsk_install_dos
public _tsk_remove_dos
;
;
include tsk.mac
;
CSECT = 2ah ; Critical Section Interrupt
get_in_use_flag = 34h ; DOS-function to get in_use_flag address
;
;
intseg segment at 0
org 20h*4
termoff dw ? ; program terminate vector
termseg dw ?
org 21h*4
idosoff dw ? ; dos interrupt
idosseg dw ?
org 25h*4
absreadoff dw ? ; absolute disk read
absreadseg dw ?
org 26h*4
abswriteoff dw ? ; absolute disk write
abswriteseg dw ?
org 27h*4
keepoff dw ? ; Terminate but stay resident
keepseg dw ?
org 28h*4
idleoff dw ? ; dos idle interrupt
idleseg dw ?
org CSECT*4
csectoff dw ? ; dos critical section
csectseg dw ?
;
intseg ends
;
;----------------------------------------------------------------------------
;
; externally defined variables
;
extrn _tsk_current: dword
extrn _lower_dos: resource
extrn _upper_dos: resource
extrn _critical: flag
;
; externally defined functions
;
extrn _asm_request_resource: far
extrn _asm_release_resource: far
extrn _asm_set_flag: far
extrn _asm_clear_flag: far
extrn _asm_wait_flag_clear: far
extrn _asm_remove_tasker: far
extrn scheduler: far
;
.data
;
;
term_err_msg db 0dh,0ah,"Program terminated - CTask uninstalled"
db 0dh,0ah,'$'
;
idle_active db 0 ; Idle-Interrupt active
dos310 db 0 ; DOS version >= 3.10
;
;
.data?
;
in_use dd ? ; Adress of DOS in-use-flag
in_error dd ? ; Adress of DOS error-mode-flag
;
;
idle_ss dw ? ; Stack save
idle_sp dw ?
;
dw 256 dup(?) ; Stack for IDLE-Interrupt
local_stack label word
;
.code
;
; Original Interrupt-Entries
;
savtermoff dw ? ; Terminate vector save
savtermseg dw ?
;
savdos label dword ; original DOS-Entry
savdosoff dw ?
savdosseg dw ?
;
savidle label dword ; original IDLE-Entry
savidleoff dw ?
savidleseg dw ?
;
savcsect label dword ; Critical Section save
savcsectoff dw ?
savcsectseg dw ?
;
savabsread label dword ; Absolute Disk Read save
savabsreadoff dw ?
savabsreadseg dw ?
;
savabswrite label dword ; Absolute Disk Write save
savabswriteoff dw ?
savabswriteseg dw ?
;
savkeepoff dw ? ; Terminate resident vector save
savkeepseg dw ?
;
critsect_active db 0 ; DOS Critical Section active
ctask_active db 0 ; CTask DOS call active
crit_task dd ? ; Task requesting critical section
;
;
dos macro
pushf
cli
call cs:savdos
endm
;
;---------------------------------------------------------------------------
;
.code
;
;
; void tsk_install_dos (void)
;
; Install DOS handler
;
; Invoked by tasker_class::tasker_class
;
_tsk_install_dos proc
;
;
; Get the address of DOS's in_use-flag. This flag indicates that
; DOS is already active. This might happen if there are other
; background tasks, like popups or print spoolers, active in
; parallel to CTask.
; This is also the address of the critical error flag in DOS. Beginning
; with DOS 3.10 the flag is located one byte before the in_use_flag.
; With older DOS versions, we would have to search through DOS for the
; address. This is omitted here, but you could include the code
; for pre 3.1 versions from pages 378-379 of the MS-DOS Encyclopedia.
;
mov ah,get_in_use_flag
int 21h
mov word ptr in_use,bx
mov word ptr in_use+2,es
mov word ptr in_error+2,es
;
push bx
mov ah,30h
int 21h
pop bx
cmp al,3
jb not_dos3
cmp al,0ah
je not_dos3 ; OS/2 compatibility box
cmp ah,10
jb not_dos3
inc dos310
dec bx
mov word ptr in_error,bx
jmp short save_ints
;
not_dos3:
;
; Save old interrupt vectors
;
save_ints:
push es
xor ax,ax
mov es,ax
;
assume es:intseg
;
mov ax,termoff ; DOS
mov savtermoff,ax
mov ax,termseg
mov savtermseg,ax
;
mov ax,idosoff ; DOS
mov savdosoff,ax
mov ax,idosseg
mov savdosseg,ax
;
mov ax,idleoff ; IDLE
mov savidleoff,ax
mov ax,idleseg
mov savidleseg,ax
;
mov ax,csectoff ; Critical Section
mov savcsectoff,ax
mov ax,csectseg
mov savcsectseg,ax
;
mov ax,absreadoff ; Absolute Disk read
mov savabsreadoff,ax
mov ax,absreadseg
mov savabsreadseg,ax
;
mov ax,abswriteoff ; Absolute Disk write
mov savabswriteoff,ax
mov ax,abswriteseg
mov savabswriteseg,ax
;
mov ax,keepoff ; Terminate Resident
mov savkeepoff,ax
mov ax,keepseg
mov savkeepseg,ax
;
; Enter new Interrupt-Entries
;
cli
mov idosoff,offset dosentry ; DOS-Entry
mov idosseg,cs
mov idleoff,offset idleentry ; Idle-Entry
mov idleseg,cs
mov termoff,offset terminate_int ; Terminate Process Entry
mov termseg,cs
mov csectoff,offset critsectint ; Critical Section Entry
mov csectseg,cs
mov keepoff,offset keep_int ; Keep Process Entry
mov keepseg,cs
mov absreadoff,offset absread_int ; Absolute Disk Read Entry
mov absreadseg,cs
mov abswriteoff,offset abswrite_int ; Absolute Disk Write Entry
mov abswriteseg,cs
sti
pop es
;
ret
;
assume es:nothing
;
_tsk_install_dos endp
;
;
; void tsk_remove_dos (void)
;
; Un-install DOS handler
;
_tsk_remove_dos proc
;
; Delete resources & flags
;
push es
xor ax,ax
mov es,ax
;
assume es:intseg
;
; Restore interrupt entries
;
cli
mov ax,savtermoff
mov termoff,ax
mov ax,savtermseg
mov termseg,ax
;
mov ax,savdosoff
mov idosoff